package aiyh.utils.recordset;

import aiyh.utils.annotation.recordset.*;
import aiyh.utils.excention.BindingException;
import aiyh.utils.sqlUtil.sqlResult.impl.PrepSqlResultImpl;
import aiyh.utils.zwl.common.ToolUtil;
import weaver.conn.RecordSet;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * @author EBU7-dev1-ayh
 * create 2021/12/19 0019 14:39
 */


public class RecordsetUtil implements InvocationHandler {

    private final ToolUtil toolUtil = new ToolUtil();

    public <T> T getMapper(Class<T> tClass) {
        if (tClass == null) {
            throw new BindingException("class is null!");
        }
        if (tClass.getAnnotation(SqlMapper.class) == null) {
            throw new BindingException("can not find SqlMapper annotation!");
        }
        return (T) Proxy.newProxyInstance(tClass.getClassLoader(), new Class[]{tClass}, this);
    }


    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

        SqlHandler sqlHandler = new SqlHandler();
        toolUtil.writeDebuggerLog(String.format("%s===>Preparing to parse SQL", proxy.getClass().getName()));
        RecordSet rs = new RecordSet();
        ResultMapper resultMapper = new ResultMapper();
        Select select = method.getAnnotation(Select.class);
        if (select != null) {
//            查询
            String sql = select.value();
            boolean custom = select.custom();
            PrepSqlResultImpl handler = sqlHandler.handler(sql, custom, method, args);
            System.out.println(handler);
            if (handler.getArgs().isEmpty()) {
                rs.executeQuery(handler.getSqlStr());
            } else {
                rs.executeQuery(handler.getSqlStr(), handler.getArgs());
            }
            return resultMapper.mapperResult(rs, method, method.getReturnType());
        }
        Update update = method.getAnnotation(Update.class);

        if (update != null) {
//            查询
            String sql = update.value();
            boolean custom = update.custom();
            PrepSqlResultImpl handler = sqlHandler.handler(sql, custom, method, args);
            Class<?> returnType = method.getReturnType();
            boolean b;
            if (handler.getArgs().isEmpty()) {
                b = rs.executeUpdate(handler.getSqlStr());
            } else {
                b = rs.executeUpdate(handler.getSqlStr(), handler.getArgs());
            }
            if (returnType.equals(void.class)) {
                return null;
            }
            if (returnType.equals(int.class) || returnType.equals(Integer.class)) {
                if (b) {
                    return 1;
                } else {
                    return 0;
                }
            }
            if (returnType.equals(boolean.class) || returnType.equals(Boolean.class)) {
                return b;
            }
        }
        Insert insert = method.getAnnotation(Insert.class);
        if (insert != null) {
//            查询
            String sql = insert.value();
            boolean custom = insert.custom();
            PrepSqlResultImpl handler = sqlHandler.handler(sql, custom, method, args);
            Class<?> returnType = method.getReturnType();
            boolean b;
            if (handler.getArgs().isEmpty()) {
                b = rs.executeUpdate(handler.getSqlStr());
            } else {
                b = rs.executeUpdate(handler.getSqlStr(), handler.getArgs());
            }
            if (returnType.equals(void.class)) {
                return null;
            }
            if (returnType.equals(boolean.class) || returnType.equals(Boolean.class)) {
                return b;
            }
        }
        Delete delete = method.getAnnotation(Delete.class);
        if (delete != null) {
//            查询
            String sql = delete.value();
            boolean custom = delete.custom();
            PrepSqlResultImpl handler = sqlHandler.handler(sql, custom, method, args);
            Class<?> returnType = method.getReturnType();
            boolean b;
            if (handler.getArgs().isEmpty()) {
                b = rs.executeUpdate(handler.getSqlStr());
            } else {
                b = rs.executeUpdate(handler.getSqlStr(), handler.getArgs());
            }
            if (returnType.equals(void.class)) {
                return null;
            }
            if (returnType.equals(boolean.class) || returnType.equals(Boolean.class)) {
                return b;
            }
        }
        return null;
    }

}
